// 初始化数据
const initData = () => {
  clearInterval(timer);
  snakeInfo = {
    // 移动方向
    direction: directionInfo.right,
    // 蛇体
    snakeBody: [
      { x: 0, y: 0, domComponent: "", flag: "body" },
      { x: 1, y: 0, domComponent: "", flag: "body" },
      { x: 2, y: 0, domComponent: "", flag: "body" },
      { x: 3, y: 0, domComponent: "", flag: "head" },
    ],
  };
  score = 0;
};
/**
 * 初始化信息
 */
const restartGame = () => {
  mapContainer.innerHTML = `
      <!-- 开始按钮 -->
      <button class="button hide" data-name="startBtn">
        <p  data-name="startBtn">开始游戏</p>
      </button>
      <!-- 结束按钮 -->
      <button class="button hide" data-name="pauseBtn">
        <p data-name="pauseBtn">继续游戏</p>
      </button>
  `;
  initData();
  // 1. 绘制蛇
  drawSnake(snakeInfo);

  // 2. 绘制食物
  drawFood();

  // 3. 开始移动
  moveSnake();
};
/**
 * 绘制蛇
 * @param {*} snake
 */
const drawSnake = (snake) => {
  // 1. 遍历蛇体
  for (let i = 0; i < snake.snakeBody.length; i++) {
    // 2. 获取蛇体元素
    const { x, y, domComponent, flag } = snake.snakeBody[i];
    if (!domComponent) {
      // 3. 创建蛇体元素
      const snakeBodyDom = document.createElement("div");
      // 4. 添加类名
      if (flag === "head") {
        snakeBodyDom.classList.add("snake-head");
        snakeBodyDom.style.transform = snakeInfo.direction.transform;
      } else {
        snakeBodyDom.classList.add("snake-body");
      }
      // 5. 设置位置
      snakeBodyDom.style.left = x * snakeBody + "px";
      snakeBodyDom.style.top = y * snakeBody + "px";
      snake.snakeBody[i].domComponent = snakeBodyDom;
      // 6. 添加到地图
      mapContainer.appendChild(snakeBodyDom);
    }
  }
};

/**
 * 绘制食物
 */
const drawFood = () => {
  while (true) {
    // 1. 随机生成位置
    food.x = Math.floor(Math.random() * tr);
    food.y = Math.floor(Math.random() * td);
    // 2. 判断是否在蛇体
    let flag = true;
    for (let i = 0; i < snakeInfo.snakeBody.length; i++) {
      const bodyItem = snakeInfo.snakeBody[i];
      if (food.x === bodyItem.x && food.y === bodyItem.y) {
        flag = false;
        break;
      }
    }
    if (flag) {
      break;
    }
  }
  const foodDom = document.createElement("div");
  foodDom.classList.add("food");
  foodDom.style.left = food.x * snakeBody + "px";
  foodDom.style.top = food.y * snakeBody + "px";
  food.domComponent = foodDom;
  mapContainer.appendChild(foodDom);
};

const handleKeydown = (e) => {
  // 1. 获取按键
  const key = e.key;
  // 2. 根据按键判断方向
  if (["w", "ArrowUp"].includes(key) && snakeInfo.direction.flag !== "bottom") {
    snakeInfo.direction = directionInfo.top;
  } else if (
    ["a", "ArrowLeft"].includes(key) &&
    snakeInfo.direction.flag !== "right"
  ) {
    snakeInfo.direction = directionInfo.left;
  } else if (
    ["s", "ArrowDown"].includes(key) &&
    snakeInfo.direction.flag !== "top"
  ) {
    snakeInfo.direction = directionInfo.bottom;
  } else if (
    ["d", "ArrowRight"].includes(key) &&
    snakeInfo.direction.flag !== "left"
  ) {
    snakeInfo.direction = directionInfo.right;
  }
};

/**
 * 碰撞检测
 * @param {*} headInfo
 */
const isCollise = (headInfo) => {
  const colliseInfo = {
    collise: false,
    eat: false,
  };
  // 1. 检测是否撞墙
  if (
    headInfo.x < 0 ||
    headInfo.x >= tr ||
    headInfo.y < 0 ||
    headInfo.y >= td
  ) {
    colliseInfo.collise = true;
    return colliseInfo;
  }
  // 2. 检测是否撞到蛇身
  for (let i = 0; i < snakeInfo.snakeBody.length; i++) {
    const bodyItem = snakeInfo.snakeBody[i];
    if (headInfo.x === bodyItem.x && headInfo.y === bodyItem.y) {
      colliseInfo.collise = true;
      return colliseInfo;
    }
  }
  // 3. 检测是否吃到食物
  if (headInfo.x === food.x && headInfo.y === food.y) {
    colliseInfo.eat = true;
  }
  return colliseInfo;
};

/**
 * 执行移动
 */
const moveSnake = () => {
  timer = setInterval(() => {
    snakeMove();
  }, moveTime);
};
/**
 * 蛇移动
 */
const snakeMove = () => {
  const { x, y } = snakeInfo.direction;
  const oldHead = snakeInfo.snakeBody[snakeInfo.snakeBody.length - 1];
  const newHead = {
    x: oldHead.x + x,
    y: oldHead.y + y,
    domComponent: "",
    flag: "head",
  };
  const colliseInfo = isCollise(newHead);
  if (colliseInfo.collise) {
    clearInterval(timer);
    if (
      window.confirm(`游戏结束，当前分数是${score}分，需要重新开始游戏吗？`)
    ) {
      restartGame();
    } else {
      clearInterval(timer);
      // 移除暂停按钮
      document.querySelector("[data-name='pauseBtn']").classList.add("hide");
      // 显示开始按钮
      document.querySelector("[data-name='startBtn']").classList.remove("hide");
    }
    return;
  }
  if (!colliseInfo.eat) {
    // 移除蛇尾
    const oldTail = snakeInfo.snakeBody.shift();
    mapContainer.removeChild(oldTail.domComponent);
  } else {
    mapContainer.removeChild(food.domComponent);
    drawFood();
    score++;
  }
  // 3. 蛇头移动
  snakeInfo.snakeBody.push(newHead);
  oldHead.flag = "body";
  oldHead.domComponent.classList.remove("snake-head");
  oldHead.domComponent.classList.add("snake-body");
  // 4. 绘制蛇头
  drawSnake(snakeInfo);
};

/**
 * 绑定事件
 */
const bindEvent = () => {
  document.addEventListener("keydown", handleKeydown);
  document.querySelector(".game-container").addEventListener("click", (e) => {
    const { name } = e.target.dataset;
    const startBtn = document.querySelector("[data-name='startBtn']");
    const pauseBtn = document.querySelector("[data-name='pauseBtn']");
    if (name === "startBtn") {
      // 点击的开始游戏按钮
      startBtn.classList.remove("show");
      startBtn.classList.add("hide");
      restartGame();
    } else if (name === "pauseBtn") {
      // 点击的暂停按钮
      pauseBtn.classList.remove("show");
      pauseBtn.classList.add("hide");
      moveSnake();
    } else if (!startBtn.className.includes("show")) {
      // 点击的容器，且开始游戏按钮未显示
      pauseBtn.classList.remove("hide");
      pauseBtn.classList.add("show");
      clearInterval(timer);
    }
  });
};

/**
 * 初始化游戏
 */
const initGame = () => {
  // 1. 绘制蛇
  drawSnake(snakeInfo);

  // 2. 绘制食物
  drawFood();

  // 3. 绑定事件
  bindEvent();
};
initGame();
